//
//  GLViewController.mm
//  Lesson 9
//
//  Created by wq on 11-8-26.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "GLViewController.h"
#import "GLView.h"
#import "glues.h"

@interface GLViewController ()

@property(nonatomic, retain) EAGLContext *context;
@property(nonatomic, assign) CADisplayLink *dispLink;

-(void)drawFrame;

@end


@implementation GLViewController

@synthesize animating;
@dynamic frameInterval;

@synthesize context;
@synthesize dispLink;

- (void)didReceiveMemoryWarning {
	[super didReceiveMemoryWarning];
}

- (void)viewDidUnload {
	[super viewDidUnload];
}

- (void)dealloc {
	[context release];
	[super dealloc];
}

-(id)init {
	self = [super init];
	if (self) {
		EAGLContext *ctx = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
		self.context = ctx;
		[ctx release];
		
		GLView *v = [[GLView alloc] initWithFrame:[UIScreen mainScreen].bounds];
		self.view = v;
		[v release];
		
		v.viewCtrl = self;
		v.context = context;
		[v initViewport];
		
		animating = NO;
		frameInterval = 2;
		
		glEnable(GL_TEXTURE_2D);
		glGenTextures(1, textures);
		NSString *path = [[NSBundle mainBundle] pathForResource:@"Star" ofType:@"png" inDirectory:@"res"];
		CGImageRef imgRef = [UIImage imageWithContentsOfFile:path].CGImage;
		
		GLuint width = CGImageGetWidth(imgRef);
		GLuint height = CGImageGetHeight(imgRef);
		void *imageData = malloc( height * width * 4 );
		CGContextRef cgContex = CGBitmapContextCreate( imageData, width, height, 8, 4 * width,
													  CGImageGetColorSpace(imgRef), kCGImageAlphaPremultipliedLast );
		
		CGContextDrawImage( cgContex, CGRectMake( 0, 0, width, height ), imgRef );
		
		glBindTexture(GL_TEXTURE_2D, textures[0]);
		
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
					 GL_UNSIGNED_BYTE, imageData);
		CGContextRelease(cgContex);
		free(imageData);
		
		_twinkle = true;
		_tilt = 90.f;
		
		for (int i = 0; i < STAR_NUM; i++) {
			_stars[i].r = rand() % 256;
			_stars[i].g = rand() % 256;
			_stars[i].b = rand() % 256;
			
			_stars[i].dist = MAX_DSIT * i / STAR_NUM;
		}
	}
	return self;
}

-(void)startAnimation {
	if (!animating) {
		CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(drawFrame)];
		self.dispLink = displayLink;
		[displayLink setFrameInterval:frameInterval];
		[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
		animating = YES;
	}
}

-(void)stopAnimation {
	if (animating) {
		[dispLink invalidate];
		self.dispLink = nil;
		animating = NO;
	}
}

-(void)drawFrame {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();
	
	gluLookAtf(0.0f, 0.0f, 415.6921938165306f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
	
	glDisable(GL_DEPTH_TEST);
	
	static const GLfloat vertices[] = {
		-15.f, -15.f, 0.f,
		15.f, -15.f, 0.f,
		-15.f, 15.f, 0.f,
		15.f, 15.f, 0.f,
	};
	
	static const GLfloat texCoords[] = {
		0.f, 1.f,
		1.f, 1.f,
		0.f, 0.f,
		1.f, 0.f,
	};
	
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	
	glVertexPointer(3, GL_FLOAT, 0, vertices);
	glTexCoordPointer(2, GL_FLOAT, 0, texCoords);

	static GLfloat spin = 0.f;
	
	for (int i = 0; i < STAR_NUM; i++) {
		glPushMatrix();
		glRotatef(_tilt, 1.f, 0.f, 0.f);
		glRotatef(_stars[i].angle, 0.f, 1.f, 0.f);
		glTranslatef(_stars[i].dist, 0.f, 0.f);
		glRotatef(-_stars[i].angle, 0.f, 1.f, 0.f);
		glRotatef(-_tilt, 1.f, 0.f, 0.f);
		
		if (_twinkle) {
			glColor4ub(_stars[STAR_NUM - 1 - i].r, _stars[STAR_NUM - 1 - i].g, _stars[STAR_NUM - 1 - i].b, 255);
			glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
		}
		
		glRotatef(spin, 0.f, 0.f, 1.f);
		glColor4ub(_stars[i].r, _stars[i].g, _stars[i].b, 255);
		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
		glPopMatrix();
		
		spin += 0.3f;
		_stars[i].angle += GLfloat(i) / STAR_NUM;
		_stars[i].dist -= 1.0f;
		
		if (_stars[i].dist < 0.f) {
			_stars[i].dist = MAX_DSIT;
			_stars[i].r = rand() % 256;
			_stars[i].g = rand() % 256;
			_stars[i].b = rand() % 256;
		}
	}
	
	[(GLView *)self.view presentRenderbuffer];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
	
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
	_tilt += 5.f;
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
	_twinkle = !_twinkle;
}

@end
